package com.winsdom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.winsdom.entity.*;
import com.winsdom.exception.BusinessException;
import com.winsdom.mapper.*;
import com.winsdom.service.PaymentService;
import com.winsdom.vo.uniformCharge.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentReceiptMapper paymentReceiptMapper;

    @Autowired
    private BillsMapper billsMapper;

    @Autowired
    private WriteOffRecordMapper writeOffRecordMapper;

    @Autowired
    private InvoiceApplicationMapper invoiceApplicationMapper;

    @Autowired
    private BillingMainMapper billingMainMapper;

    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private UnifiedChargingMapper unifiedChargingMapper;

    @Transactional
    @Override
    public void handlePaymentSuccess(String outTradeNo, ChargeRequestDTO chargeRequestDTO) throws Exception {
        // 根据收款流水号查询收款记录
        PaymentReceipt paymentReceipt = paymentReceiptMapper.selectOne(
                new QueryWrapper<PaymentReceipt>().eq("receipt_serial", outTradeNo)
        );

        if (paymentReceipt == null) {
            throw new RuntimeException("收款记录未找到，订单号：" + outTradeNo);
        }

        // 查询包含 billingMainId 的 BillingVO
        List<BillingVO> billingVOs = unifiedChargingMapper.getBillingDetailsByIds(chargeRequestDTO.getDetailIds());
        if (billingVOs.isEmpty()) {
            throw new RuntimeException("计费明细未找到，流水号：" + outTradeNo);
        }


        for (BillingVO vo : billingVOs) {
            BigDecimal detailAmount = vo.getAmountSubtotal();
            Long billingMainId = vo.getBillingMainId();

            if (billingMainId == null) {
                throw new BusinessException("账单主表 ID 为空，明细 ID：" + vo.getDetailId(), HttpStatus.BAD_REQUEST);
            }
            // 查询与billing_main_id关联的账单记录
            List<Bills> billsList = billsMapper.selectList(
                    new QueryWrapper<Bills>()
                            .eq("billing_main_id", billingMainId)
                            .eq("arrears_status", 1) // 仅处理未结清账单（状态1）
            );

            if (billsList.isEmpty()) {
                log.warn("未找到未结清账单，明细ID：{}，billing_main_id：{}",  vo.getDetailId(), billingMainId);
                continue; // 跳过无效账单
            }

            for (Bills bills : billsList) {
                // 更新账单的欠费状态和金额
                BigDecimal paymentAmount = paymentReceipt.getReceiptAmount();
                BigDecimal currentArrears = bills.getArrearsAmount();
                BigDecimal newArrears = currentArrears.subtract(detailAmount).setScale(2, BigDecimal.ROUND_HALF_UP);

                if (newArrears.compareTo(BigDecimal.ZERO) <= 0) {
                    bills.setArrearsStatus(2); // 已交清
                    bills.setArrearsAmount(BigDecimal.ZERO);
                } else {
                    bills.setArrearsStatus(1); // 未结清
                    bills.setArrearsAmount(newArrears);
                }
                billsMapper.updateById(bills);

                // 生成核销记录
                WriteOffRecord writeOffRecord = new WriteOffRecord();
                writeOffRecord.setPaymentId(paymentReceipt.getPaymentId());
                writeOffRecord.setBillsId(bills.getId());
                writeOffRecord.setAmount(detailAmount);
                writeOffRecord.setWriteOffDate(LocalDateTime.now());
                writeOffRecord.setStatus(1); // 已核销
                writeOffRecordMapper.insert(writeOffRecord);

                // 生成开票申请记录
                InvoiceApplication invoiceApplication = new InvoiceApplication();
                invoiceApplication.setBillsId(bills.getId());
                invoiceApplication.setApplyAmount(detailAmount);
                invoiceApplication.setStatus(1); // 开票
                invoiceApplication.setInvoiceType(chargeRequestDTO.getInvoiceType());
                invoiceApplication.setNoticeNumber("NOTICE_" + System.currentTimeMillis());
                invoiceApplication.setHeaderId(chargeRequestDTO.getHeaderId());
                invoiceApplicationMapper.insert(invoiceApplication);
            }
        }


        //获取客户名称
        Customer customer = customerMapper.selectById(chargeRequestDTO.getCustomerId());
        log.info("客户名称: {}", customer.getCustomerName());
        String customerName = customer != null ? customer.getCustomerName() : "未知客户";

        // 更新收款记录状态
        paymentReceipt.setStatus(1); // 支付成功
        paymentReceipt.setReceiptTime(LocalDateTime.now());
        paymentReceipt.setUpdateTime(LocalDateTime.now());
        paymentReceipt.setPayerName(customerName);//付款人——客户
//        paymentReceipt.setPayerCustomerName();//TODO 付款业主
//        paymentReceipt.setPayeeAccount();//TODO 收款账号
        paymentReceiptMapper.updateById(paymentReceipt);

    }

    @Transactional
    @Override
    public void handleTemporaryPayment(String outTradeNo, ChargeRequestDTO chargeRequestDTO) throws Exception {
        // 根据收款流水号查询收款记录
        PaymentReceipt paymentReceipt = paymentReceiptMapper.selectOne(
                new QueryWrapper<PaymentReceipt>().eq("receipt_serial", outTradeNo)
        );

        if (paymentReceipt == null) {
            throw new RuntimeException("收款记录未找到，订单号：" + outTradeNo);
        }

        // 创建临时账单
        BillingMain temporaryBillingMain = new BillingMain();
        temporaryBillingMain.setBillingPeriod(LocalDate.now().toString());
        temporaryBillingMain.setCustomerId(Long.valueOf(chargeRequestDTO.getCustomerId()));
//        temporaryBillingMain.setExpenditureId(chargeRequestDTO.getExpenditureId());
        temporaryBillingMain.setOrganizationName("临时计费");
        temporaryBillingMain.setProjectName("临时项目");
        temporaryBillingMain.setBuildingName("临时楼栋");
        temporaryBillingMain.setFloorName("临时楼层");
        temporaryBillingMain.setReceivableAmount(paymentReceipt.getReceiptAmount());
        temporaryBillingMain.setStatus(2); // 已入账
        billingMainMapper.insert(temporaryBillingMain);

        // 关联临时账单到收款记录
//        paymentReceipt.setBillingMainId(temporaryBillingMain.getId());
        paymentReceiptMapper.updateById(paymentReceipt);

        // 创建临时账单记录
        Bills temporaryBill = new Bills();
        temporaryBill.setBillingMainId(temporaryBillingMain.getId());
        temporaryBill.setArrearsStatus(2); // 已结清
        temporaryBill.setArrearsAmount(BigDecimal.ZERO);
        // 设置其他必要字段...
        billsMapper.insert(temporaryBill);

        // 生成核销记录
        WriteOffRecord writeOffRecord = new WriteOffRecord();
        writeOffRecord.setPaymentId(paymentReceipt.getPaymentId());
        writeOffRecord.setBillsId(temporaryBill.getId());
        writeOffRecord.setAmount(paymentReceipt.getReceiptAmount());
        writeOffRecord.setWriteOffDate(LocalDateTime.now());
        writeOffRecord.setStatus(1); // 已核销
        writeOffRecordMapper.insert(writeOffRecord);

        // 生成开票申请记录
        InvoiceApplication invoiceApplication = new InvoiceApplication();
        invoiceApplication.setBillsId(temporaryBillingMain.getId());
        invoiceApplication.setApplyAmount(paymentReceipt.getReceiptAmount());
        invoiceApplication.setStatus(1); // 开票
        invoiceApplication.setInvoiceType(chargeRequestDTO.getInvoiceType());
        invoiceApplication.setNoticeNumber("NOTICE_" + System.currentTimeMillis());
        invoiceApplication.setHeaderId(chargeRequestDTO.getHeaderId());
        invoiceApplicationMapper.insert(invoiceApplication);
    }
}
